import { ShElement } from './ShElement'
import { ShPopup } from './ShPopup'


export class ShMenuItem extends ShElement {

    private $subMenu: ShMenu | null = null

    public isMounted: boolean = false

    constructor() {
        super()

        this.$shadow.innerHTML = `
            <style>
                :host {
                    line-height: 2em;
                    display: flex;
                }
                :host(:hover) {
                    background-color: var(--color-primary);
                    color: white;
                }
                span {
                    display: inline-block;
                    height: 2em;
                }
                span:nth-child(2) {
                    width: 2em;
                    text-align: center;
                }
                span:nth-child(3) {
                    min-width: 10em;
                }
                span:nth-child(5) {
                    width: 2em;
                    text-align: center;
                    display: flex;
                    align-items: center;
                    justify-content: right;
                }
            </style>
            <span></span>
            <span id="text"></span>
            <span></span>
            <span></span>
        `
    }

    connectedCallback() {
        for (let i = 0; i < this.children.length; i++) {
            const $item = this.children[i] as ShMenuItem
            if ($item.tagName !== 'SH-MENU-ITEM')
                continue
            
            if (! this.$subMenu) {
                // 在自己的第四个 span 中增加一个右箭头图标
                const $span = this.$shadow.lastElementChild! as HTMLElement
                $span.innerHTML = `
                    <svg width="20" height="20" viewBox="0 0 48 48" fill="none">
                        <path d="M19 12L31 24L19 36" stroke="#333" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
                    </svg>
                `
                this.$subMenu = new ShMenu()

                this.$subMenu.on('shev-popup-show', () => {
                    this.addClass('sh-selected')
                    // 如果存在子菜单，则将 '>' 图标改为白色
                    $span.firstElementChild?.firstElementChild?.classList.add('sh-selected')
                })

                this.$subMenu.on('shev-popup-hide', () => {
                    this.removeClass('sh-selected')
                    // 如果存在子菜单，则恢复 '>' 图标颜色
                    $span.firstElementChild?.firstElementChild?.classList.remove('sh-selected')
                })                
            }

            this.$subMenu.addItem($item)
            // 注意：上个语句会把 $item 从 this.children 中移除，所以 i 要减 1
            i--
        }
    }

    static observedAttributes = ['text',]

    attributeChangedCallback(name: string, _: any, newValue: string) {
        if (name === 'text') {
            if (newValue === '-') {
                this.$shadow.innerHTML = `
                    <style>
                        :host {
                            margin: 0.5em 0;
                            border-bottom: var(--border-ctrl);
                        }
                    </style>
                `
            } else {
                this.$shadow.getElementById('text')!.textContent = newValue
            }
        }
    }

    public get text(): string {
        return this.getAttribute('text') || ''
    }

    public set text(value: string) {
        this.setAttribute('text', value)
    }

    public hasSubMenu(): boolean {
        return this.$subMenu !== null
    }

    public showSubMenu() {
        this.$subMenu?.show({
            $ref: this,
            position: 'top-right',
            anchor: 'top-left',
            offset: { top: -4, left: 0 },
        })
    }

    public hideSubMenu() {
        this.$subMenu?.hide()
    }
}
customElements.define('sh-menu-item', ShMenuItem)


/**
 * 可弹出和隐藏的菜单面板。
 */
export class ShMenu extends ShPopup {
    
    private $expanedItem: ShMenuItem | null = null

    constructor() {
        super()

        const $style = document.createElement('style')
        $style.textContent = `
            :host {
                padding: 3px;
                display: flex;
                flex-direction: column;
            }
            span {
                margin: 0.5em 0;
                border-bottom: var(--border-ctrl);
            }
        `
        // 把 $style 插入到 ShPopup 的 <style> 后面
        this.$shadow.firstElementChild!.insertAdjacentElement('afterend', $style)
    }

    connectedCallback() {
        for (let i = 0; i < this.children.length; i++) {
            const $item = this.children[i] as ShMenuItem
            if ($item.tagName === 'SH-MENU-ITEM' && !$item.isMounted)
                this.setupItem($item)
        }
    }

    public addItem($item: ShMenuItem) {
        this.setupItem($item)
        this.append($item)
    }

    public hide() {
        this.$expanedItem?.hideSubMenu()
        super.hide()
    }

    private setupItem($item: ShMenuItem) {
        $item.isMounted = true
        
        if ($item.text === '-')
            return

        // 鼠标进入菜单项时，显示或有的子菜单
        $item.on('pointerenter', () => {
            if (this.$expanedItem !== $item)
                this.$expanedItem?.hideSubMenu()
            $item.showSubMenu()
            this.$expanedItem = $item
        })

        // 鼠标点击菜单项时，如果菜单项是一个命令，则收起本菜单
        // Ps：命令的执行在菜单项的另一个 click 事件处理程序中
        $item.on('click', () => {
            if (! $item.hasSubMenu())
                this.hide()
        })
    }
}
customElements.define('sh-menu', ShMenu)